home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / cpu / tms32010 / 32010dsm.c next >
C/C++ Source or Header  |  1999-08-02  |  11KB  |  340 lines

  1. /****************************************************************************
  2.  *                Texas Instruments TMS320C10 DSP Disassembler                *
  3.  *                                                                            *
  4.  *                        Copyright (C) 1999 by Quench                        *
  5.  *        You are not allowed to distribute this software commercially.        *
  6.  *                        Written for the MAME project.                        *
  7.  *            Many thanks to those involved in the i8039 Disassembler            *
  8.  *                    as this was borrowed from it (and modified)                *
  9.  *                                                                            *
  10.  *                To be used with TMS320C10 DSP Emulator engine.                *
  11.  *                                                                            *
  12.  *                                                                            *
  13.  * A Memory address                                                            *
  14.  * B Branch Address for Branch instructions (Requires next opcode read)        *
  15.  * D Immediate byte load                                                    *
  16.  * K Immediate bit  load                                                    *
  17.  * W Immediate word load (Actually 13 bit)                                    *
  18.  * M AR[x] register modification type (for indirect addressing)                *
  19.  * N ARP register to change ARP pointer to (for indirect addressing)        *
  20.  * P I/O port address number                                                *
  21.  * R AR[R] register to use                                                    *
  22.  * S Shift ALU left                                                            *
  23.  ***************************************************************************/
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <ctype.h>
  29.  
  30. #include "memory.h"
  31.  
  32. #ifdef  MAME_DEBUG
  33. #include "mamedbg.h"
  34. #endif
  35.  
  36. typedef unsigned char byte;
  37. typedef unsigned short int word;
  38.  
  39. #define FMT(a,b) a, b
  40. #define PTRS_PER_FORMAT 2
  41.  
  42. #ifdef LSB_FIRST
  43. #define READOP16(a)   ((cpu_readop(a)<<8)|cpu_readop((a)+1))
  44. #define READARG16(a)  ((cpu_readop_arg(a)<<8)|cpu_readop_arg((a)+1))
  45. #else
  46. #define READOP16(a)   ((cpu_readop(a))|(cpu_readop((a)+1)<<8))
  47. #define READARG16(a)  ((cpu_readop_arg(a))|(cpu_readop_arg((a)+1)<<8))
  48. #endif
  49.  
  50. char *arith[4] = { "*" , "*-" , "*+" , "??" } ;
  51. char *nextar[4] = { ",AR0" , ",AR1" , "" , "" } ;
  52.  
  53. char *TMSFormats[] = {
  54.     FMT("0000ssss0aaaaaaa", "add  %A%S"),
  55.     FMT("0000ssss10mmn00n", "add  %M%S%N"),
  56.     FMT("0001ssss0aaaaaaa", "sub  %A%S"),
  57.     FMT("0001ssss10mmn00n", "sub  %M%S%N"),
  58.     FMT("0010ssss0aaaaaaa", "lac  %A%S"),
  59.     FMT("0010ssss10mmn00n", "lac  %M%S%N"),
  60.     FMT("0011000r0aaaaaaa", "sar  %R,%A"),
  61.     FMT("0011000r10mmn00n", "sar  %R%M%N"),
  62.     FMT("0011100r0aaaaaaa", "lar  %R,%A"),
  63.     FMT("0011100r10mmn00n", "lar  %R%M%N"),
  64.     FMT("01000ppp0aaaaaaa", "in   %A,%P"),
  65.     FMT("01000ppp10mmn00n", "in   %M,%P%N"),
  66.     FMT("01001ppp0aaaaaaa", "out  %A,%P"),
  67.     FMT("01001ppp10mmn00n", "out  %M,%P%N"),
  68.     FMT("01010sss0aaaaaaa", "sacl %A"),        /* This instruction has a shift but */
  69.     FMT("01010sss10mmn00n", "sacl %M%N"),    /* is documented as not performed */
  70.     FMT("01011sss0aaaaaaa", "sach %A%S"),
  71.     FMT("01011sss10mmn00n", "sach %M%S%N"),
  72.     FMT("011000000aaaaaaa", "addh %A"),
  73.     FMT("0110000010mmn00n", "addh %M%N"),
  74.     FMT("011000010aaaaaaa", "adds %A"),
  75.     FMT("0110000110mmn00n", "adds %M%N"),
  76.     FMT("011000100aaaaaaa", "subh %A"),
  77.     FMT("0110001010mmn00n", "subh %M%N"),
  78.     FMT("011000110aaaaaaa", "subs %A"),
  79.     FMT("0110001110mmn00n", "subs %M%N"),
  80.     FMT("011001000aaaaaaa", "subc %A"),
  81.     FMT("0110010010mmn00n", "subc %M%N"),
  82.     FMT("011001010aaaaaaa", "zalh %A"),
  83.     FMT("0110010110mmn00n", "zalh %M%N"),
  84.     FMT("011001100aaaaaaa", "zals %A"),
  85.     FMT("0110011010mmn00n", "zals %M%N"),
  86.     FMT("011001110aaaaaaa", "tblr %A"),
  87.     FMT("0110011110mmn00n", "tblr %M%N"),
  88.     FMT("011010001000000k", "larp %K"),
  89.     FMT("011010000aaaaaaa", "mar  %A"),        /* Actually this is executed as a NOP */
  90. /*    FMT("0110100010mmn00n", "mar  %M%N"),    */
  91. /*    MAR indirect has been expanded out to all its variations because one of */
  92. /*    its opcodes is the same as LARP (actually performs the same function) */
  93.  
  94.     FMT("0110100010001000", "mar  *"),
  95.     FMT("0110100010001001", "mar  *"),
  96.     FMT("0110100010010000", "mar  *-,AR0"),
  97.     FMT("0110100010010001", "mar  *-,AR1"),
  98.     FMT("0110100010011000", "mar  *-"),
  99.     FMT("0110100010011001", "mar  *-"),
  100.     FMT("0110100010100000", "mar  *+,AR0"),
  101.     FMT("0110100010100001", "mar  *+,AR1"),
  102.     FMT("0110100010101000", "mar  *+"),
  103.     FMT("0110100010101001", "mar  *+"),
  104.     FMT("0110100010110000", "mar  ??,AR0"),
  105.     FMT("0110100010110001", "mar  ??,AR1"),
  106.     FMT("0110100010111000", "mar  ??"),
  107.     FMT("0110100010111001", "mar  ??"),
  108.  
  109.     FMT("011010010aaaaaaa", "dmov %A"),
  110.     FMT("0110100110mmn00n", "dmov %M%N"),
  111.     FMT("011010100aaaaaaa", "lt   %A"),
  112.     FMT("0110101010mmn00n", "lt   %M%N"),
  113.     FMT("011010110aaaaaaa", "ltd  %A"),
  114.     FMT("0110101110mmn00n", "ltd  %M%N"),
  115.     FMT("011011000aaaaaaa", "lta  %A"),
  116.     FMT("0110110010mmn00n", "lta  %M%N"),
  117.     FMT("011011010aaaaaaa", "mpy  %A"),
  118.     FMT("0110110110mmn00n", "mpy  %M%N"),
  119.     FMT("011011100000000k", "ldpk %K"),
  120.     FMT("011011110aaaaaaa", "ldp  %A"),
  121.     FMT("0110111110mmn00n", "ldp  %M%N"),
  122.     FMT("0111000rdddddddd", "lark %R,%D"),
  123.     FMT("011110000aaaaaaa", "xor  %A"),
  124.     FMT("0111100010mmn00n", "xor  %M%N"),
  125.     FMT("011110010aaaaaaa", "and  %A"),
  126.     FMT("0111100110mmn00n", "and  %M%N"),
  127.     FMT("011110100aaaaaaa", "or   %A"),
  128.     FMT("0111101010mmn00n", "or   %M%N"),
  129.     FMT("011110110aaaaaaa", "lst  %A"),
  130.     FMT("0111101110mmn00n", "lst  %M%N"),
  131.     FMT("011111000aaaaaaa", "sst  %A"),
  132.     FMT("0111110010mmn00n", "sst  %M%N"),
  133.     FMT("011111010aaaaaaa", "tblw %A"),
  134.     FMT("0111110110mmn00n", "tblw %M%N"),
  135.     FMT("01111110dddddddd", "lack %D"),
  136.     FMT("0111111110000000", "nop"),            /* 7F80 */
  137.     FMT("0111111110000001", "dint"),
  138.     FMT("0111111110000010", "eint"),
  139.     FMT("0111111110001000", "abs"),            /* 7F88 */
  140.     FMT("0111111110001001", "zac"),
  141.     FMT("0111111110001010", "rovm"),
  142.     FMT("0111111110001011", "sovm"),
  143.     FMT("0111111110001100", "cala"),
  144.     FMT("0111111110001101", "ret"),
  145.     FMT("0111111110001110", "pac"),
  146.     FMT("0111111110001111", "apac"),
  147.     FMT("0111111110010000", "spac"),
  148.     FMT("0111111110011100", "push"),
  149.     FMT("0111111110011101", "pop"),            /* 7F9D */
  150.     FMT("100wwwwwwwwwwwww", "mpyk %W"),
  151.     FMT("1111010000000000bbbbbbbbbbbbbbbb", "banz %B"),
  152.     FMT("1111010100000000bbbbbbbbbbbbbbbb", "bv   %B"),
  153.     FMT("1111011000000000bbbbbbbbbbbbbbbb", "bioz %B"),
  154.     FMT("1111100000000000bbbbbbbbbbbbbbbb", "call %B"),
  155.     FMT("1111100100000000bbbbbbbbbbbbbbbb", "b    %B"),
  156.     FMT("1111101000000000bbbbbbbbbbbbbbbb", "blz  %B"),
  157.     FMT("1111101100000000bbbbbbbbbbbbbbbb", "blez %B"),
  158.     FMT("1111110000000000bbbbbbbbbbbbbbbb", "bgz  %B"),
  159.     FMT("1111110100000000bbbbbbbbbbbbbbbb", "bgez %B"),
  160.     FMT("1111111000000000bbbbbbbbbbbbbbbb", "bnz  %B"),
  161.     FMT("1111111100000000bbbbbbbbbbbbbbbb", "bz   %B"),
  162.     NULL
  163. };
  164.  
  165. #define MAX_OPS (((sizeof(TMSFormats) / sizeof(TMSFormats[0])) - 1) / PTRS_PER_FORMAT)
  166.  
  167. typedef struct opcode {
  168.     word mask;            /* instruction mask */
  169.     word bits;            /* constant bits */
  170.     word extcode;        /* value that gets extension code */
  171.     char *parse;        /* how to parse bits */
  172.     char *fmt;            /* instruction format */
  173. } TMS32010Opcode;
  174.  
  175. static TMS32010Opcode Op[MAX_OPS+1];
  176. static int OpInizialized = 0;
  177.  
  178. static void InitDasm32010(void)
  179. {
  180.     char *p, **ops;
  181.     word mask, bits;
  182.     int bit;
  183.     int i;
  184.  
  185.     ops = TMSFormats; i = 0;
  186.     while (*ops)
  187.     {
  188.         p = *ops;
  189.         mask = 0; bits = 0; bit = 15;
  190.         while (*p && bit >= 0)
  191.         {
  192.             switch (*p++)
  193.             {
  194.                 case '1': mask |= 1<<bit; bits |= 1<<bit; bit--; break;
  195.                 case '0': mask |= 1<<bit; bit--; break;
  196.                 case ' ': break;
  197.                 case 'a':
  198.                 case 'b':
  199.                 case 'd':
  200.                 case 'k':
  201.                 case 'm':
  202.                 case 'n':
  203.                 case 'p':
  204.                 case 'r':
  205.                 case 's':
  206.                 case 'w':
  207.                     bit --;
  208.                     break;
  209.                 default: printf("Invalid instruction encoding '%s %s'\n",
  210.                     ops[0],ops[1]);
  211.                     exit(1);
  212.             }
  213.         }
  214.         if (bit != -1 )
  215.         {
  216.             printf("not enough bits in encoding '%s %s' %d\n",
  217.                 ops[0],ops[1],bit);
  218.             exit(1);
  219.         }
  220.         while (isspace(*p)) p++;
  221.         if (*p) Op[i].extcode = *p;
  222.         Op[i].bits = bits;
  223.         Op[i].mask = mask;
  224.         Op[i].fmt = ops[1];
  225.         Op[i].parse = ops[0];
  226.  
  227.         ops += PTRS_PER_FORMAT;
  228.         i++;
  229.     }
  230.  
  231.     OpInizialized = 1;
  232. }
  233.  
  234. int Dasm32010(char *str, unsigned pc)
  235. {
  236.     int a, b, d, k, m, n, p, r, s, w;    /* these can all be filled in by parsing an instruction */
  237.     int i;
  238.     int op;
  239.     int cnt = 1;
  240.     int code;
  241.     int bit;
  242.     char *strtmp;
  243.     char *cp;                /* character pointer in OpFormats */
  244.  
  245.     if (!OpInizialized) InitDasm32010();
  246.  
  247.     op = -1;                /* no matching opcode */
  248.     code = READOP16(2*pc);
  249.     for ( i = 0; i < MAX_OPS; i++)
  250.     {
  251.         if ((code & Op[i].mask) == Op[i].bits)
  252.         {
  253.             if (op != -1)
  254.             {
  255.                 printf("Error: opcode %04Xh matches %d (%s) and %d (%s)\n",
  256.                     code,i,Op[i].fmt,op,Op[op].fmt);
  257.             }
  258.             op = i;
  259.         }
  260.     }
  261.     if (op == -1)
  262.     {
  263.         sprintf(str,"???? dw %04Xh",code);
  264.         return cnt;
  265.     }
  266.     strtmp = str;
  267.     if (Op[op].extcode)
  268.     {
  269.         bit = 31;
  270.         code <<= 16;
  271.         code |= READARG16(2*(pc+cnt));
  272.         cnt++;
  273.     }
  274.     else
  275.     {
  276.         bit = 15;
  277.     }
  278.  
  279.     /* shift out operands */
  280.     cp = Op[op].parse;
  281.     a = b = d = k = m = n = p = r = s = w = 0;
  282.  
  283.     while (bit >= 0)
  284.     {
  285.         /* printf("{%c/%d}",*cp,bit); */
  286.         switch(*cp)
  287.         {
  288.             case 'a': a <<=1; a |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  289.             case 'b': b <<=1; b |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  290.             case 'd': d <<=1; d |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  291.             case 'k': k <<=1; k |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  292.             case 'm': m <<=1; m |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  293.             case 'n': n <<=1; n |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  294.             case 'p': p <<=1; p |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  295.             case 'r': r <<=1; r |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  296.             case 's': s <<=1; s |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  297.             case 'w': w <<=1; w |= ((code & (1<<bit)) ? 1 : 0); bit--; break;
  298.             case ' ': break;
  299.             case '1': case '0':  bit--; break;
  300.             case '\0': printf("premature end of parse string, opcode %x, bit = %d\n",code,bit); exit(1);
  301.         }
  302.         cp++;
  303.     }
  304.  
  305.     /* now traverse format string */
  306.     cp = Op[op].fmt;
  307.     while (*cp)
  308.     {
  309.         if (*cp == '%')
  310.         {
  311.             char num[15], *q;
  312.             cp++;
  313.             switch (*cp++)
  314.             {
  315.                 case 'A': sprintf(num,"$%02X",a); break;
  316.                 case 'B': sprintf(num,"$%04X",b); break;
  317.                 case 'D': sprintf(num,"%02Xh",d); break;
  318.                 case 'K': sprintf(num,"%d",k); break;
  319.                 case 'N': sprintf(num,"%s",nextar[n]); break;
  320.                 case 'M': sprintf(num,"%s",arith[m]); break;
  321.                 case 'P': sprintf(num,"PA%d",p); break;
  322.                 case 'R': sprintf(num,"AR%d",r); break;
  323.                 case 'S': sprintf(num,",%d",s); break;
  324.                 case 'W': sprintf(num,"%04Xh",w); break;
  325.                 default:
  326.                     printf("illegal escape character in format '%s'\n",Op[op].fmt);
  327.                     exit(1);
  328.             }
  329.             q = num; while (*q) *str++ = *q++;
  330.             *str = '\0';
  331.         }
  332.         else
  333.         {
  334.             *str++ = *cp++;
  335.             *str = '\0';
  336.         }
  337.     }
  338.     return cnt;
  339. }
  340.